package com.qdlc.p2p.biz.service;

import java.text.MessageFormat;
import java.util.List;

import javax.annotation.Resource;

import com.qd.p2p.adapter.AdaptedRequestHandleService;
import com.qd.p2p.sina.pay.enums.AccountType;
import com.qd.p2p.sina.pay.enums.IdentityType;
import com.qd.p2p.sina.pay.enums.PayType;
import com.qd.p2p.sina.pay.param.CreateHostingCollectTradeParam;
import com.qd.p2p.sina.pay.param.DepositExtendParam;
import com.qd.p2p.sina.pay.response.CreateHostingCollectTradeResponse;
import com.qd.p2p.sina.service.SinaPayService;
import com.qdlc.p2p.common.constant.Summary;
import com.qdlc.p2p.common.constant.TradeCode;
import com.qdlc.p2p.common.constant.TradeStatus;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.core.redis.JedisCache;
import com.qdlc.p2p.common.core.redis.JedisCacheFactory;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.OrderNoUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.dto.TppTradeLog;

/**
 * 代收模版类
 * 代收通用逻辑处理类
 * <p/>
 *
 * @author wuaj
 */
public abstract class AbstractCollectService implements CollectPayService {

    @Resource
    protected TppTradeService tppTradeService;

    @Resource
    protected SinaPayService sinaPayService;
    
    @Resource
    protected AdaptedRequestHandleService paySerivce;

    protected JedisCache<String> jedisCacheString = JedisCacheFactory.newInstance(String.class);

    @Override
    public boolean preCreateOrder() {
        return true;
    }

    @Override
    public void aftCreateOrder(TppTradeLog tppTradeLog) {
    }

    @Override
    public List<TppTradeLog> createOrders(Object... pars) {
        return null;
    }

    @Override
    public TppTradeLog createOrder(Object... pars) {
        analyzePars(pars);
        if (preCreateOrder()) {
            // 生成订单号
            String orderNo = OrderNoUtil.getInstance().getSerialNumber();
            // 可变参数
            TppTradeLog tppTradeLog = getTppTradeLog();
            // 固定参数
            tppTradeLog.setRemark(getBusinessName().concat("订单生成"));
            tppTradeLog.setOrderNo(orderNo); // 订单号
            tppTradeLog.setAssociateOrderId(orderNo);  // 自个关联
            tppTradeLog.setTradeStatus(TradeStatus.TRADE_STATUS_WAIT_PAY.getStatus());
            tppTradeLog.setAddTime(DateUtil.getNow()); // 交易时间
            tppTradeLog.setAmount(0d);                 // 交易金额
            tppTradeService.save(tppTradeLog);
            aftCreateOrder(tppTradeLog);
            return tppTradeLog;
        }
        return null;
    }
    
    @Override
    public ReturnResult requestOrder(TppTradeLog tppTradeLog) {
    	CreateHostingCollectTradeResponse response = null;
    	try {
    		Summary summary = Summary.getSummaryByType(tppTradeLog.getServiceType());
    		IdentityType identityType = IdentityType.EMAIL.name().equals(tppTradeLog.getIdentityType()) ?
    				IdentityType.EMAIL : IdentityType.UID;
    		AccountType accountType = identityType == IdentityType.EMAIL ? AccountType.BASIC : AccountType.SAVING_POT;
    		
    		// 调用代收接口
    		CreateHostingCollectTradeParam param = new CreateHostingCollectTradeParam();
    		param.setOutTradeNo(tppTradeLog.getOrderNo())
    		.setOutTradeCode(TradeCode.C1001)
    		.setPayerId(tppTradeLog.getTppUserCustId())
    		.setPayerIdentityType(identityType)
    		.setAmount(tppTradeLog.getMoney())
    		.setSummary(summary.getSummaryName() + tppTradeLog.getOrderNo())
    		.setCanRepayOnFailed("N")
    		.setNotifyUrl(getCallBackUrl());
    		DepositExtendParam extend = new DepositExtendParam();
    		extend.setPayType(PayType.balance);
    		extend.setAccountType(accountType);
    		param.setPayParam(extend);
    		if (!isSuspend(tppTradeLog.getTradeType())) {
    			response = sinaPayService.createHostingCollectTrade(param);
    		}
    	} catch (Exception e) {
    		// do nothing 调用失败
    	}
    	if (response != null && response.success()) {
    		tppTradeLog.setRemark(getBusinessName().concat("提交成功"));
    		tppTradeService.update(tppTradeLog);
    		requestOrderSuccess(tppTradeLog); // 请求成功处理
    	} else {
    		String message = response == null ? "RPC调用失败" : MessageFormat.format("{0}代收失败!ReqStatus:{1} ReqErrorMessage:{2} ResCode:{3} ResMessage:{4}",
    				getBusinessName(), response.getReqStatus(), response.getReqErrorMessage(), response.getResponseCode(),
    				response.getResponseMessage());
    		String responseMessage = response == null ? "RPC调用失败" : response.getResponseMessage();
    		logger.info(message);
    		
    		// 置为废单
    		tppTradeLog.setTradeStatus(TradeStatus.TRADE_STATUS_INVALID.getStatus());
    		tppTradeLog.setRemark(getBusinessName().concat("提交失败-" + responseMessage));
    		tppTradeService.update(tppTradeLog);
    		
    		requestOrderFail(tppTradeLog); // 请求失败处理
    		return new ReturnResult(true, message);
    	}
    	return ReturnResult.SUCCESS;
    }

    @Override
    public void requestOrderSuccess(TppTradeLog tppTradeLog) {
    }

    @Override
    public void requestOrderFail(TppTradeLog tppTradeLog) {
    }

    /**
     * 交易完成状态更新
     */
    protected void tradeFinishForStatus(TppTradeLog tppTradeLog, String depositStatus, double tradeAmount) {
        tppTradeLog.setAmount(tradeAmount); // 实际交易金额
        tppTradeLog.setTradeTime(DateUtil.getNow()); // 交易成功时间
        tppTradeService.updateTradeLog(tppTradeLog, depositStatus, getBusinessName().concat("交易完成"));
    }

    /**
     * 交易成功状态更新
     */
    protected void tradeSuccessForStatus(TppTradeLog tppTradeLog, String depositStatus) {
        tppTradeLog.setTradeTime(DateUtil.getNow()); // 交易完成时间
        tppTradeService.updateTradeLog(tppTradeLog, depositStatus, getBusinessName().concat("交易成功"));
    }

    /**
     * 交易失败状态更新
     */
    protected void tradeFailForStatus(TppTradeLog tppTradeLog, String depositStatus) {
        tppTradeLog.setTradeTime(DateUtil.getNow()); // 交易失败时间
        tppTradeService.updateTradeLog(tppTradeLog, depositStatus, getBusinessName().concat("交易失败"));
    }

    /**
     * 代收是否需要挂起
     */
    protected boolean isSuspend(String tradeType) {
        if (StringUtil.isNotEmpty(tradeType)) {
            String suspend = jedisCacheString.get("SP_" + tradeType);
            return StringUtil.isNotEmpty(suspend) && suspend.equals("true");
        }
        return false;
    }
}
